package com.vois.jack.btmgr.classicbase;

import android.bluetooth.BluetoothProfile;

import com.vois.jack.btmgr.util.Logger;

abstract public class DefaultSppBtDevice extends BtDevice {
    private Logger logger = Logger.getLogger(DefaultSppBtDevice.class);
    static private final int DATA_RECV_INIT     = 0x01;
    static private final int DATA_RECV_PAYLOAD  = 0x02;
    private int dataRecvState;
    private int maxBufferSize;
    private byte[] dataBuffer;
    private int curRecvSize;

    protected void setRecvState(boolean init) {
        if (init) {
            dataRecvState = DATA_RECV_INIT;
        }else {
            dataRecvState = DATA_RECV_PAYLOAD;
        }
    }

    public int getCurRecvSize() {
        return curRecvSize;
    }

    @Override
    protected void onSppSocketConnecting() {
        super.onSppSocketConnecting();
        dataRecvState = DATA_RECV_INIT;
        maxBufferSize = getMaxSppPacketDataSize();
        dataBuffer = new byte[maxBufferSize];
        curRecvSize = 0;
    }

    @Override
    protected void onSppSocketDisconnected() {
        super.onSppSocketDisconnected();
        dataBuffer = null;
        curRecvSize = 0;
        dataRecvState = DATA_RECV_INIT;
    }

    abstract protected int processRecvInitState(byte[] data, int dataSize, int curPos);

    abstract protected int processRecvPayloadState(byte[] data, int dataSize, int curPos);

    @Override
    protected void onBtConnectStateChanged(int profile, int curState) {
        super.onBtConnectStateChanged(profile, curState);
        if (profile == BluetoothProfile.HEADSET) {
            if (curState == BluetoothProfile.STATE_CONNECTED) {
                connectSpp();
            }
        }
    }

    int processDataRecved(byte[] data, int dataSize) {
        int curPos = 0;
        int processPos = 0;

        while (curPos < dataSize) {
            switch (dataRecvState) {
                case DATA_RECV_INIT: {
                    processPos = processRecvInitState(data, dataSize, curPos);
                }
                break;

                case DATA_RECV_PAYLOAD: {
                    processPos = processRecvPayloadState(data, dataSize, curPos);
                }
                break;
            }

            //logger.d("processPos:" + processPos + " curPos:" + curPos);
            if (curPos == processPos) {
                break;
            }

            curPos = processPos;
        }

        return curPos;

    }

    @Override
    protected void onSppDataRecv(byte[] buffer, int bufferSize) {
        int curPos = 0;
        //logger.dumpArray(buffer, bufferSize);
        if (curRecvSize + bufferSize < maxBufferSize) {
            System.arraycopy(buffer, 0, dataBuffer, curRecvSize, bufferSize);
            curRecvSize += bufferSize;
            curPos = processDataRecved(dataBuffer, curRecvSize);
            //logger.d("curPos:" + curPos + " curRecvSize:" + curRecvSize);
            if (curPos < curRecvSize && curPos != 0) {
                for (int i = curPos, j = 0; i < curRecvSize; i++, j++) {
                    dataBuffer[j] = dataBuffer[i];
                }
            }

            curRecvSize -= curPos;
        }
    }

    @Override
    protected int getMaxSppPacketDataSize() {
        return 4096;
    }
}
